<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
  </head>
  <body>
    <style>
      ul {
        list-style: none;
      }
    </style>
    <input type="text" />
    <ul></ul>

    <script>
      /**
       * 我们在JS33做过一个难度更高的深度监听对象，这里就写个简单的浅监听吧
       * 关于监听原理与注意事项，可以参考JS33
       * 抛开原理不谈，咱来说说怎么实现的双向绑定
       * 修改input的值，调用方法修改person.weight的值，
       * 属性值发生变化在set中调用_render函数，在该函数将内容渲染上去
       *
       * 如果是直接改变了属性值，触发set调用_render函数，不仅更新了页面文字的值还更新了输入框的值
       */
      var ul = document.querySelector("ul");
      var person = {
        sex: "男",
        age: "25",
        name: "王大锤",
        height: 28,
        weight: 32,
      };
      var inp = document.querySelector("input");
      inp.value = person.weight;
      const _render = () => {
        var str = `<li>姓名：<span>${person.name}</span></li>
                           <li>性别：<span>${person.sex}</span></li>
                           <li>年龄：<span>${person.age}</span></li>
                           <li>身高：<span>${person.height}</span></li>
                           <li>体重：<span>${person.weight}</span></li>`;
        ul.innerHTML = str;
        inp.value = person.weight;
      };
      _render(ul);
      // 补全代码
      inp.oninput = () => {
        person.weight = inp.value;
      };

      const updateview = (obj) => {
        Object.keys(obj).forEach((item) => {
          let value = obj[item];
          Object.defineProperty(obj, item, {
            get: () => value,
            set: (newValue) => {
              value = newValue;
              _render();
            },
          });
        });
      };
      updateview(person);
      person.weight = 999;
    </script>
  </body>
</html>
